package kd.xkqj.unittest.plugin.action;

import com.intellij.notification.NotificationDisplayType;
import com.intellij.notification.NotificationGroup;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.LogicalPosition;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;

import javax.management.Notification;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @description: TODO
 * @author feng_jun_peng
 * @create 2024-12-19 10:13 
 * @version 1.0
 */
public class AnActionHelper {
    /**
     * description: 获取当前文件路径
     * @author: feng_jun_peng
     * @create: 2024-12-19 09:19
     * @param e: 文件路径
     * @return: java.lang.String
     */
    public static String getCurrentFilePath(AnActionEvent e) {
        PsiFile currentFile = e.getData(PlatformDataKeys.PSI_FILE);
        var directoryPath = getCurrentDirectoryPath(e);
        var filePath = currentFile.getContainingDirectory().toString().replace("PsiDirectory:", "") + "\\" + currentFile.getOriginalFile().getName();
        return filePath;
    }

    /**
     * description: 获取当前文件目录路径
     * @author: feng_jun_peng
     * @create: 2024-12-19 14:01
     * @param e: 文件上级目录路径
     * @return: java.lang.String
     */
    public static String getCurrentDirectoryPath(AnActionEvent e) {
        PsiFile currentFile = e.getData(PlatformDataKeys.PSI_FILE);
        var directoryPath = currentFile.getContainingDirectory().toString().replace("PsiDirectory:", "");
        return directoryPath;
    }

    /**
     * description: 获取当前光标的行
     * @author: feng_jun_peng
     * @create: 2024-12-19 09:14
     * @param e:
     * @return: int
     */
    public static int getEditorCursorLine(AnActionEvent e) {
        // 获取当前编辑器
        Editor editor = e.getData(com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR);
        // 获取光标位置
        CaretModel caretModel = editor.getCaretModel();
        LogicalPosition logicalPosition = caretModel.getLogicalPosition();
        return logicalPosition.line;
    }

    /**
     * description: 获取指定文件行信息
     * @author: feng_jun_peng
     * @create: 2024-12-19 09:17
     * @param line: 行号
     * @param sourceFilePath: 文件路径
     * @return: java.lang.String
     */
    public static String getLineMessage(int line, String sourceFilePath) {
        if (line == -1) {
            return null;
        }
        List<@NotNull String> lineMessages = null;
        try {
            lineMessages = Files.readAllLines(Path.of(sourceFilePath), StandardCharsets.UTF_8);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        if (lineMessages.size() < line) {
            return null;
        }
        return lineMessages.get(line);
    }

    /**
     * description: 从磁盘重新加载指定文件
     * @author: feng_jun_peng
     * @create: 2024-12-19 10:39
     * @param project: IDEA项目
     * @param filePath: 文件路径
     * @param cursorLine: 需要聚焦的行，-1则不聚焦
     * @return: void
     */
    public static void reloadFileFromDisk(Project project, String filePath, int cursorLine) {
        VirtualFile file = VfsUtil.findFileByIoFile(new File(filePath), true);
        if (file != null) {
            // 使用 refresh() 强制从磁盘加载文件
            file.refresh(false, false);

            // 如果需要在写入线程中执行相关操作，可以使用 WriteCommandAction
            WriteCommandAction.runWriteCommandAction(project, () -> {
                // 任何你想在重新加载后执行的操作
                // 使用 FileEditorManager 打开指定文件
                FileEditorManager fileEditorManager = FileEditorManager.getInstance(project);
                fileEditorManager.openFile(file, true); // 第二个参数 true 表示聚焦到编辑器
                if (cursorLine < 0)
                    return;

                Editor editor = null;
                TextEditor textEditor = null;
                if (fileEditorManager.getSelectedEditor(file) instanceof TextEditor) {
                    editor = ((TextEditor) fileEditorManager.getSelectedEditor(file)).getEditor();
                }
                if (editor == null)
                    return;

                // 移动光标到指定行（行号从 1 开始）
                CaretModel caretModel = editor.getCaretModel();
                LogicalPosition logicalPosition = new LogicalPosition(cursorLine, 0); // 行号从 0 开始
                caretModel.moveToLogicalPosition(logicalPosition);

                // 滚动到目标行
                editor.getScrollingModel().scrollToCaret(com.intellij.openapi.editor.ScrollType.CENTER);

            });
        }
    }

    /**
     * description: 显示普通通知
     * @author: feng_jun_peng
     * @create: 2024-12-19 15:02
     * @param project:
     * @param title:
     * @param content:
     * @param durationInMillis: 毫秒数，默认3秒
     * @return: void
     */
    public static void showNotification(Project project, String title, String content, int durationInMillis) {
        // 创建 NotificationGroup
        NotificationGroup notificationGroup = new NotificationGroup("KD UnitTest Plugin", NotificationDisplayType.BALLOON, true);

        // 创建通知
        var notification = notificationGroup.createNotification(
                "title",
                "",
                content,
                NotificationType.INFORMATION
        );

        // 显示通知
        Notifications.Bus.notify(notification, project);

        if (durationInMillis == 0)
            durationInMillis = 3000;

        // 设置定时关闭
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                notification.expire(); // 手动关闭通知
            }
        }, durationInMillis);
    }
}
